package com.earthea.application.common.entity;

import cn.hutool.http.HttpStatus;
import com.earthea.common.exception.EartheaException;
import com.earthea.common.exception.IErrorCode;
import lombok.Data;
import org.apache.commons.lang3.reflect.ConstructorUtils;

/**
 * 公共响应体
 */
@Data
public class BaseResponse implements IErrorCode {
    private int code;

    private String msg;

    private Object data;

    /**
     * 成功返回结果
     */
    public static BaseResponse success() {
        return success(BaseResponse.class);
    }

    /**
     * 成功返回结果
     */
    public static <T extends BaseResponse> T success(Class<T> clz) {
        T response = build(clz);
        response.setCode(HttpCodeEnum.SUCCESS.getCode());
        response.setMsg(HttpCodeEnum.SUCCESS.getMsg());
        return response;
    }

    /**
     * 失败返回结果
     *
     * @param errorCode 错误码
     */
    public static <T extends BaseResponse> T failed(IErrorCode errorCode, Class<T> clz) {
        T response = build(clz);
        response.setCode(errorCode.getCode());
        response.setMsg(errorCode.getMsg());
        return response;
    }

    /**
     * 失败返回结果
     *
     * @param code    错误码
     * @param message 错误信息
     */
    public static <T extends BaseResponse> T failed(int code, String message, Class<T> clz) {
        T response = build(clz);
        response.setCode(code);
        response.setMsg(message);
        return response;
    }

    /**
     * 失败返回结果
     *
     * @param message 提示信息
     */
    public static <T extends BaseResponse> T failed(String message, Class<T> clz) {
        T response = build(clz);
        response.setCode(HttpCodeEnum.FAIL.getCode());
        response.setMsg(message);
        return response;
    }

    /**
     * 失败返回结果
     */
    public static <T extends BaseResponse> T failed(Class<T> clz) {
        return failed(HttpCodeEnum.FAIL, clz);
    }

    /**
     * 失败返回结果
     */
    public static BaseResponse failed() {
        return failed(HttpCodeEnum.FAIL, BaseResponse.class);
    }

    /**
     * 失败返回结果
     */
    public static BaseResponse failed(String message) {
        return failed(message, BaseResponse.class);
    }

    private static <T extends BaseResponse> T build(Class<T> clz) {
        try {
            return ConstructorUtils.invokeConstructor(clz);
        } catch (Exception e) {
            throw new EartheaException(e);
        }
    }

    public boolean isFailed() {
        return !isSuccess();
    }

    public boolean isSuccess() {
        return HttpStatus.HTTP_OK == getCode();
    }

    @Override
    public int getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }
}
